package utils;

import beans.HttpConfig;
import dao.SocketLogDao;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author zhuyaokunll@foxmail.com
 * @date 2018/7/30 13:22
 */
public class SocketHandleThread extends Thread {
    private Socket socket;
    private DataOutputStream out;
    private DataInputStream in;
    private SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
    private String socketLogFileUri = HttpConfig.socketLogFileUri;
    private String socketLogLevel = HttpConfig.socketLogLevel;
    private SocketLogDao socketLogDao = new SocketLogDao();
    private int index;

    public SocketHandleThread(Socket t,int index){
        this.index = index;
        Log4jInit.logger.info(index+"号客户端连接进来...");
        socket = t;
        try{
            in = new DataInputStream(socket.getInputStream());
            out = new DataOutputStream(socket.getOutputStream());
        }catch(IOException e){
            e.printStackTrace();
        }
    }

    public void run()
    {
        try{
            while(true){
                if(in.available()>0){
                    byte b = in.readByte();
                    switch(b) {
                        case 'F':{
                            Log4jInit.logger.info("收到客户端"+index+"发送日志文件操作");

                            int nLen = in.readInt();
                            byte[] bId = new byte[nLen];
                            in.read(bId,0,nLen);
                            String id = new String(bId, "ISO-8859-1");

                            nLen = in.readInt();
                            byte[] bPsn = new byte[nLen];
                            in.read(bPsn,0,nLen);
                            String psn = new String(bPsn, "ISO-8859-1");


                            nLen = in.readInt();
                            byte[] bName = new byte[nLen];
                            in.read(bName,0,nLen);
                            //解析文件名称，其为utf-8的编码格式
                            String logName = new String(bName, "gbk");
                            logName = new String(logName.getBytes("UTF-8"));
                            String socketLogFilePath = socketLogFileUri+sf.format(new Date())+"-"+logName;
                            FileOutputStream fsOut = new FileOutputStream(socketLogFilePath);

                            long mLen = in.readLong();
                            Log4jInit.logger.info("日志文件长度："+mLen);

                            Log4jInit.logger.info("算法id="+id+"，psn="+psn+"，日志文件名："+logName+"，长度为"+nLen);

                            byte[] bArray;
                            if(mLen>4096) {
                                bArray= new byte[4096];
                            }else {
                                bArray= new byte[(int) mLen];
                            }

                            long remainLen=mLen;
                            //将文件内容进行从gbk到utf-8的编码格式转化
                            while(remainLen>0) {
                                if(remainLen>4096) {
                                    in.read(bArray,0,4096);
                                    String temp = new String(bArray,"gbk");
                                    fsOut.write(temp.getBytes("UTF-8"));
                                    remainLen -=4096;
                                }
                                else {
                                    in.read(bArray,0,(int) remainLen);
                                    String temp = new String(bArray,"gbk");
                                    fsOut.write(temp.getBytes("utf-8"));
                                    remainLen -=remainLen;
                                }
                            }

                            fsOut.close();
                            Log4jInit.logger.info("接收日志文件完毕，发送返回值\n");
                            //发送返回信息
                            out.write("F1".getBytes(), 0, 2);
                            socketLogDao.insertLogFileUri(socketLogLevel, socketLogFilePath, psn, id);
                            break;
                        }
                        case 'M':{
                            Log4jInit.logger.info("收到客户端"+index+"发送消息操作");
                            FileOutputStream fsOut = new FileOutputStream("jcptMessage.log",true);

                            int nLen = in.readInt();
                            byte[] bId = new byte[nLen];
                            in.read(bId,0,nLen);
                            String id = new String(bId, "ISO-8859-1");

                            nLen = in.readInt();
                            byte[] bPsn = new byte[nLen];
                            in.read(bPsn,0,nLen);
                            String psn = new String(bPsn, "ISO-8859-1");

                            int mLen = in.readInt();
                            Log4jInit.logger.info("消息长度:"+mLen);
                            byte[] bArray = new byte[mLen];
                            in.read(bArray,0,mLen);
                            fsOut.write(bArray);
                            fsOut.close();
                            String message = new String(bArray, "GBK");
                            Log4jInit.logger.info("收到来自客户端"+index+"的消息：id="+id+",psn="+psn+",消息："+message+"\n");
                            //发送返回信息
                            out.write("M1".getBytes(), 0, 2);
                            socketLogDao.insertLogMessage(socketLogLevel,message,psn,id);
                            break;
                        }case 'S':{
                            //2018-7-12记录一下，这里status的值只可能是1或者0，1：算法运行成功；0：算法运行失败
                            Log4jInit.logger.info("收到客户端"+index+"发送的算法执行状态信息");
                            int nLen = in.readInt();
                            byte[] bId = new byte[nLen];
                            in.read(bId,0,nLen);
                            String id = new String(bId, "ISO-8859-1");

                            nLen = in.readInt();
                            byte[] bPsn = new byte[nLen];
                            in.read(bPsn,0,nLen);
                            String psn = new String(bPsn, "ISO-8859-1");

                            //这里需要保证status的值必须为0或者1
                            int status = in.readInt();
                            Log4jInit.logger.info("算法:id="+id+",psn="+psn+",执行状态为："+status+"\n");
                            //发送返回信息
                            out.write("S1".getBytes(), 0, 2);
                            socketLogDao.insertAlgorithmState(socketLogLevel,status+"",psn,id,null);
                            break;
                        }case 'P':{
                            Log4jInit.logger.info("收到客户端"+index+"发送的算法执行进度信息");
                            int nLen = in.readInt();
                            byte[] bId = new byte[nLen];
                            in.read(bId,0,nLen);
                            String id = new String(bId, "ISO-8859-1");

                            nLen = in.readInt();
                            byte[] bPsn = new byte[nLen];
                            in.read(bPsn,0,nLen);
                            String psn = new String(bPsn, "ISO-8859-1");

                            int process = in.readInt();
                            Log4jInit.logger.info("算法:id="+id+",psn="+psn+"，执行进度为："+process+"\n");
                            //发送返回信息
                            out.write("P1".getBytes(), 0, 2);
                            socketLogDao.insertAlgorithmSchedule(socketLogLevel,process+"",psn,id);
                            break;
                        }
                        default:
                            Log4jInit.logger.info("wrong operate code");
                    }
                }
            }
        }
        //出现错误退出循环，结束本次socket通信
        catch (IOException e) {
            e.printStackTrace();
            Log4jInit.logger.info("客户端"+index+"离去");
        }
        this.interrupt();
    }
}
